program emcalc32;

uses
  Forms,
  Windows,
  SysUtils,
  ShlObj,
  ComObj,
  ActiveX,
  XPMan,
  MainForm in 'MainForm.pas' {fmEMCLauncher},
  uBaseCalcForm in 'uBaseCalcForm.pas' {fmBaseCalcForm},
  uBaseDivForm in 'uBaseDivForm.pas' {fmBaseDivForm},
  uSimpleDivForm in 'uSimpleDivForm.pas' {fmSimpleDiv},
  uENoms in 'uENoms.pas',
  uAdjDivForm in 'uAdjDivForm.pas' {fmAdjDivForm},
  uLEDCalc in 'uLEDCalc.pas' {fmLEDCalc},
  uFormReg in 'uFormReg.pas',
  uAVRTimerForm in 'uAVRTimerForm.pas' {fmAVRTimerCalc},
  u34063Calc in 'u34063Calc.pas' {fm34063},
  uColorDecoder in 'uColorDecoder.pas' {fmColorDecoder},
  pxml in 'pxml.pas',
  WideStrUtils in 'WideStrUtils.pas',
  uLocalization in 'uLocalization.pas',
  uOhmLawForm in 'uOhmLawForm.pas' {fmOhmLaw},
  uTL431 in 'uTL431.pas' {fmTL431},
  uZenerCalc in 'uZenerCalc.pas' {fmZenerCalc},
  uRCFilterForm in 'uRCFilterForm.pas' {fmRCFilterCalc},
  uMergeElmForm in 'uMergeElmForm.pas' {fmMergeElmCalc},
  uCableDrop in 'uCableDrop.pas' {fmCableDropCalc},
  uLM2576 in 'uLM2576.pas' {fmLM2576},
  uLM2576Rev in 'uLM2576Rev.pas' {fmLM2576Rev},
  uCapResForm in 'uCapResForm.pas' {fmCapRes},
  uConfig in 'uConfig.pas',
  uLangSelectForm in 'uLangSelectForm.pas' {fmLangSelect},
  uGraphForm in 'uGraphForm.pas' {fmGraph},
  uXYList in 'uXYList.pas',
  uTimeFreqCalc in 'uTimeFreqCalc.pas' {fmTimeFreqCalc},
  uSepicCalcForm in 'uSepicCalcForm.pas' {fmSepicCalc},
  uOPAmpCalcForm in 'uOPAmpCalcForm.pas' {fmOPAmpCalc},
  uLCDCharGen in 'uLCDCharGen.pas' {fmHD44780CG};

{$R *.res}
{$R bitmaps.res}

type
  PRC = ^RC;
  RC = record
    Data: string;
  end;

procedure _enum(const ACalcClass: TBaseCalcFormClass; AUser: pointer); stdcall;
var s: string;
begin
  s := GetString('#'+ACalcClass.RunKey+'\title', false);
  if (s='') then s := ACalcClass.CalcFriendlyName;

  PRC(AUser)^.Data := PRC(AUser)^.Data+Format('"%s %s" - %s'#13#10, [
      ExtractFileName(ParamStr(0)),
      ACalcClass.RunKey, S]);
end;

procedure ShowKeys();
var r: RC;
begin
  r.Data := '';
  //r.Data := ExtractFileName('"'+ParamStr(0))+' /lnk" - Create desktop icons'#13#10#13#10;
  EnumCalcClasses(_enum, @r);
  r.Data := r.Data+#13#10'add -debug parameter to show/run debug state calculator';
  r.Data := r.Data+#13#10'Note: Debug calculators may show incorrect results.'#13#10'They are still in development state.';
  //r.Data := trim(r.Data);
  Application.MessageBox(PChar(r.Data),'EMCalc Commands', MB_ICONINFORMATION or MB_OK);
end;

function GetDesktopFolder: string;
var
  PIDList: PItemIDList;
  Buffer: array [0..MAX_PATH-1] of Char;
begin
  Result := '';
  SHGetSpecialFolderLocation(Application.Handle, CSIDL_DESKTOP, PIDList);
  if Assigned(PIDList) then
    if SHGetPathFromIDList(PIDList, Buffer) then
      Result := Buffer;
end;

function CreateDesktopShellLink(const TargetName, ALinkName, ALinkArgs, AIcon: string): Boolean;
var
  IObject: IUnknown;
  ISLink: IShellLink;
  IPFile: IPersistFile;
  PIDL: PItemIDList;
  LinkName: string;
  InFolder: array [0..MAX_PATH-1] of Char;
begin
  Result := False;

  IObject := CreateComObject(CLSID_ShellLink);
  ISLink := IObject as IShellLink;
  IPFile := IObject as IPersistFile;

  with ISLink do begin
    SetDescription('Description ...');
    SetPath(PChar(TargetName));
    if (ALinkArgs<>'') then SetArguments(PChar(ALinkArgs));
    if (AIcon<>'') and FileExists(AIcon) then SetIconLocation(PAnsiChar(AIcon),0);
    SetWorkingDirectory(PChar(ExtractFilePath(TargetName)));
  end;

  SHGetSpecialFolderLocation(0, CSIDL_DESKTOPDIRECTORY, PIDL);
  SHGetPathFromIDList(PIDL, InFolder) ;

  LinkName := IncludeTrailingPathDelimiter(GetDesktopFolder);
  LinkName := LinkName + (*ExtractFileName(TargetName)*)ALinkName + '.lnk';

  if not FileExists(LinkName) then
    if IPFile.Save(PWideChar(wideString(LinkName)), False) = S_OK then
      Result := True;
end;

procedure _enum_di(const ACalcClass: TBaseCalcFormClass; AUser: pointer); stdcall;
begin
  CreateDesktopShellLink(ParamStr(0), ACalcClass.CalcFriendlyName, ACalcClass.RunKey, AppDir+'Data\ico_'+ACalcClass.RunKey+'.ico');
end;

procedure CreateDesktopLinks();
begin
  EnumCalcClasses(_enum_di, nil);
  Application.MessageBox('Desktop icons created','EMCalc', MB_ICONINFORMATION or MB_OK);
end;

var pf: TBaseCalcFormClass;
begin
  (*
  if (ParamStr(1)='/lnk') then begin
    CoInitialize(nil);
    CreateDesktopLinks;
    CoUninitialize();
    exit;
  end;
  *)
  Application.Initialize;

  if Config.AsString['main.language',''] = '' then
    Config.AsString['main.language',''] := TfmLangSelect.Invoke;
  AutoLoadLocale;
  InitStringConst;
  
  pf := nil;
  if (ParamStr(1)<>'') then
    pf := FindCalcByKey(ParamStr(1));
  if (pf<>nil) then begin
    pf.InvokeCalc;
  end else
  //  ShowKeys;
  if (ParamStr(1) = '/?') then ShowKeys
  else
  Application.CreateForm(TfmEMCLauncher, fmEMCLauncher);
  Application.Run;
  ReleaseRegisters;
end.
